//package com.wangfei.lecture.SM;
//
//import java.util.ArrayList;
//import java.util.Collection;
//import java.util.Collections;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//import java.util.Random;
//import org.apache.commons.codec.binary.Base64;
//import com.google.gson.reflect.TypeToken;
//import unionpay.BytesUtil;
//import unionpay.GsonUtil;
//
//public class YH_FindCard {
//    // 银联sm2公钥：由银联侧提供
//    private static final String SM2_PUBLIC_KEY = "04750e6b8b938a008b8660689f03a8358effe645546d377c2f746f2380f660908a9a1fd5091c7b5c646f66b0c14f14ebe7b8929cfe69cabf1136caabffc60f474b";
//
//    // 银行侧sm2私钥：银行侧自己使用案例代码生成
//    private static final String privateKey = "b57abcb8326611b298794ce1a3cb37bd7c36548ae8b8b8dac01a1c54a1cf32b3";
//
//    /**
//     * 拼接签名字符串
//     *
//     * @param map
//     * @return
//     */
//    public static String sortMapToSTring(Map<String, String> map) {
//        StringBuilder result = new StringBuilder();
//        Collection<String> keySet = map.keySet();
//        List<String> list = new ArrayList<String>(keySet);
//        Collections.sort(list);
//        for (int i = 0; i < list.size(); i++) {
//            result.append(list.get(i)).append("=").append(map.get(list.get(i))).append("&");
//        }
//        return result.substring(0, result.length() - 1);
//    }
//
//    /**
//     * 生成随机数
//     *
//     * @param length
//     * @return
//     */
//    public static String createNonceStr(int length) {
//        String sl = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
//        StringBuilder bf = new StringBuilder();
//        for (int i = 0; i < length; i++) {
//            bf.append(sl.charAt(new Random().nextInt(sl.length())));
//        }
//        return bf.toString();
//    }
//
//    /**
//     * 生成sm4公钥
//     *
//     * @return
//     */
//    public static String genSM4SymmetricKey() {
//        String sl = "abcdef0123456789";
//        StringBuilder bf = new StringBuilder();
//        Random random = new Random();
//        for (int i = 0; i < 16; i++) {
//            bf.append(sl.charAt(random.nextInt(sl.length())));
//        }
//        return bf.toString();
//    }
//
//    public static void main(String[] args) throws Exception {
//        SMUtil smUtil = new SMUtil();
//        // 模拟接受到的请求报文：json格式
//        String requestStr = "{\"authorizeNo\":\"oA22wHk5BZ+ScgFWc3BB5A==\",\"certType\":\"M0sPOHyGI1g9cybFLbB8QA==\",\"findModel\":\"1\",\"extensions\":\"\",\"signature\":\"gkC0J6adVVRG9m6VIsYFrDVKVnS7sRYTFD0lbkfnlpu1oJVX8JYIHLHEic6nNOVq8YPARDTQ2jUZIJOYZZrJ2Q==\",\"appId\":\"qwertyuiop12345\",\"realNm\":\"/Z3xXbFAfB4fGLzK5sawsg==\",\"certifId\":\"BEdfHAO6xv9W0Dgud8A640vuog30en2S/4zUHihKeWQ=\",\"sn\":\"@app@0138da702006001000100000000\",\"nonceStr\":\"RLKhDY09zZfgaCTS\",\"symmetricKey\":\"041505ee6db9a69dafe52056f42f1766060f05320634d9cf28d77a3160201c597445d8fba7edfd8c44b12995dbabfe3f9f894c65ecceb5c7e15a4657180b1dd6d1490321b94adbd3bb78ef4ff5eafeb8a8a82e555aa6e2d16010be95566db9508fadedf6b009ba07854f3a3c895c52c0e0\",\"timestamp\":\"1644387107766\"}";
////        String symmetricKey = "041505ee6db9a69dafe52056f42f1766060f05320634d9cf28d77a3160201c597445d8fba7edfd8c44b12995dbabfe3f9f894c65ecceb5c7e15a4657180b1dd6d1490321b94adbd3bb78ef4ff5eafeb8a8a82e555aa6e2d16010be95566db9508fadedf6b009ba07854f3a3c895c52c0e0";
////        Map<String, Object> respMap = GsonUtil.fromJsonWithDisableHtmlEscaping(requestStr,
////                new TypeToken<Map<String, Object>>() {
////                }.getType());
////第一步：使用银行侧sm2私钥解密出对称秘钥
////        String symmetricKey = (String) respMap.get("symmetricKey");
////        System.out.println("symmetricKey:" + symmetricKey);
////        String sm4Key = smUtil.sm2Decrypt(privateKey, Hex.decode(symmetricKey));
////        System.out.println("解出来的sm4对称密钥明文：" + sm4Key);
//
////        byte[] st = smUtil.sm2Encrypt(SM2_PUBLIC_KEY, sm4Key);
////        String symmetricKey2 = Hex.toHexString(st);
////        System.out.println("转成16进制的SM4公钥：" + symmetricKey2);
////        //第二步：使用解密后的对称秘钥解密敏感字段
//        Map<String, String> map = new HashMap<>();
////        String realNm = (String) respMap.get("realNm");
////        realNm = smUtil.sm4Decrypt(sm4Key, Base64.decodeBase64(realNm));
////        System.out.println("realNm解密结果:" + realNm);
////        map.put("realNm", realNm);
////
////        String certType = (String) respMap.get("certType");
////        certType = smUtil.sm4Decrypt(sm4Key, Base64.decodeBase64(certType));
////        System.out.println("certType解密结果:" + certType);
////        map.put("certType", certType);
////
////        String certifId = (String) respMap.get("certifId");
////        certifId = smUtil.sm4Decrypt(sm4Key, Base64.decodeBase64(certifId));
////        System.out.println("certifId解密结果:" + certifId);
////        map.put("certifId", certifId);
////
////        String authorizeNo = (String) respMap.get("authorizeNo");
////        System.out.println(authorizeNo);
////        authorizeNo = smUtil.sm4Decrypt(sm4Key, Base64.decodeBase64(authorizeNo));
////        System.out.println("authorizeNo解密结果:" + authorizeNo);
////        map.put("authorizeNo", authorizeNo);
//
//        //第四步：使用银联侧sm2公钥验证签名
////        map.put("sn", respMap.get("sn").toString());
////        map.put("appId", respMap.get("appId").toString());
////        map.put("findModel", respMap.get("findModel").toString());
////        map.put("extensions", respMap.get("extensions").toString());
////        map.put("nonceStr", respMap.get("nonceStr").toString());// 随机字符串
////        map.put("timestamp", respMap.get("timestamp").toString());
////        map.put("symmetricKey", sm4Key);// 对称密钥明文
//
//        String str2 = sortMapToSTring(map);
////        System.out.println("待验签字符串：" + str2);
////        String signature = (String) respMap.get("signature");
//
//        str2 = "123456789";
//        signature = "ZqBvSb3hQhzAkVvaA9Kl5NRaoK/IICjcNuUcr89FmRWuc7j0GCsNUlf0IzCERpfMVWt2oVSUpotp2re9IjpI1Q==";
//        boolean result = smUtil.sm2SignValidate(SM2_PUBLIC_KEY, Base64.decodeBase64(signature), str2);
//        System.out.println("验签结果:" + result);
//
//        System.out.println("\n\n");
//        //第五步：返回用户银行卡数据
//        // 拼接签名内容
//        Map<String, String> maps = new HashMap<String, String>();
//        maps.put("resp", "00");
//        maps.put("msg", "成功");
//        List<Map<String,String>> cardList = new ArrayList<Map<String,String>>();
//
//        Map<String, String> card1 = new HashMap<>();
//        card1.put("cardNo", "6224****8888");
//        card1.put("issInsIdCd", "12345678");
//        card1.put("reserveMobile", "15012345678");
//        card1.put("cardAttr", "01");
//        card1.put("accountLevel", "0");
//        card1.put("accountMedia", "1");
//        card1.put("cardSt", "02");
//        card1.put("areaCode", "0002");
//        cardList.add(card1);
//
//        Map<String, String> card2 = new HashMap<>();
//        card2.put("cardNo", "6224****8889");
//        card2.put("issInsIdCd", "12345678");
//        card2.put("reserveMobile", "15012345679");
//        card2.put("cardAttr", "01");
//        card2.put("accountLevel", "0");
//        card2.put("accountMedia", "1");
//        card2.put("cardSt", "02");
//        card2.put("areaCode", "0002");
//        cardList.add(card2);
//
//        StringBuffer str = new StringBuffer();
//        for (Map<String,String> card : cardList) {
//            String str3 = sortMapToSTring(card);
//            str.append(str3).append("&");
//        }
//        if (null != str && str.length() > 0) {
//            str.deleteCharAt(str.length() - 1);
//            maps.put("cardList", str.toString());
//        }
//
//        maps.put("appId", "qwertyuiop12345");
//        maps.put("userId", "xxxxx");
//        maps.put("registerMobile", "15151553536");
//        maps.put("cardCount", "2");
//        maps.put("extensions", "xxxx");
//        maps.put("nonceStr", createNonceStr(16));// 随机字符串
//        maps.put("timestamp", String.valueOf(System.currentTimeMillis()));
//
//        String sm4PublicKey = genSM4SymmetricKey();//生成随机秘钥
//        System.out.println("生成的SM4公钥：" + sm4PublicKey);
//        maps.put("symmetricKey", sm4PublicKey);// 对称密钥明文
//
//        // 生成待签名字符串
//        String str3 = sortMapToSTring(maps);
//        System.out.println("待签名字符串：" + str3);
//
//        // SM2签名：明文参与签名
//        byte[] signBytes = smUtil.sm2Sign(privateKey, str3);
//        String base64Sign = Base64.encodeBase64String(signBytes);
//        System.out.println("base64格式的签名值:" + base64Sign);
//        maps.put("signature", base64Sign);// 签名
//
//        // 拼接应答报文
//        Map<String, Object> resultMap = new HashMap<String, Object>();
//        resultMap.putAll(maps);
//        for (Map<String,String> card : cardList) {
//            // 敏感字段加密
//            byte[] sm4CardNo = smUtil.sm4Encrypt(sm4PublicKey, card.get("cardNo"));
//            String sm4base64CardNo = Base64.encodeBase64String(sm4CardNo);
//            System.out.println("cardNo加密结果转base64:" + sm4base64CardNo);
//            card.put("cardNo", sm4base64CardNo);
//
//            byte[] sm4ReserveMobile = smUtil.sm4Encrypt(sm4PublicKey, card.get("reserveMobile"));
//            String sm4base64ReserveMobile = Base64.encodeBase64String(sm4ReserveMobile);
//            System.out.println("reserveMobile加密结果转base64:" + sm4base64ReserveMobile);
//            card.put("reserveMobile", sm4base64ReserveMobile);
//
//            byte[] sm4AreaCode = smUtil.sm4Encrypt(sm4PublicKey, card.get("areaCode"));
//            String sm4base64AreaCode = Base64.encodeBase64String(sm4AreaCode);
//            System.out.println("areaCode加密结果转base64:" + sm4base64AreaCode);
//            card.put("areaCode", sm4base64AreaCode);
//        }
//        resultMap.put("cardList", cardList);
//
//        byte[] sm4RegisterMobile = smUtil.sm4Encrypt(sm4PublicKey, resultMap.get("registerMobile").toString());
//        String sm4base64RegisterMobile = Base64.encodeBase64String(sm4RegisterMobile);
//        System.out.println("registerMobile加密结果转base64:" + sm4base64RegisterMobile);
//        resultMap.put("registerMobile", sm4base64RegisterMobile);
//
//        // 使用银联侧公钥加密sm4对称秘钥并返回
//        byte[] st = smUtil.sm2Encrypt(SM2_PUBLIC_KEY, sm4PublicKey);
//        String symmetricKey2 = BytesUtil.bytesToHex(st);
//        System.out.println("转成16进制的SM4公钥：" + symmetricKey2);
//        resultMap.put("symmetricKey", symmetricKey2);
//        //最后将响应报文以json格式返回
//        System.out.println("应答报文json：" + GsonUtil.toFilterJson(resultMap));
//    }
//    }
//}
